home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 January / EnigmA AMIGA RUN 33 (1999)(G.R. Edizioni)(IT)[!][issue 1999-01].iso / earcd / apus / boothack / old / bh980730.lha / bh980730 / linuxboot.c < prev    next >
C/C++ Source or Header  |  1980-01-05  |  51KB  |  1,879 lines

  1. /*
  2.  *  linux/arch/m68k/boot/amiga/linuxboot.c -- Generic routine to boot Linux/m68k
  3.  *                          on Amiga, used by both Amiboot and
  4.  *                          Amiga-Lilo.
  5.  *
  6.  *    Created 1996 by Geert Uytterhoeven
  7.  *
  8.  *
  9.  *  This file is based on the original bootstrap code (bootstrap.c):
  10.  *
  11.  *    Copyright (C) 1993, 1994 Hamish Macdonald
  12.  *                 Greg Harp
  13.  *
  14.  *            with work by Michael Rausch
  15.  *                 Geert Uytterhoeven
  16.  *                 Frank Neumann
  17.  *                 Andreas Schwab
  18.  *                 Jesper Skov
  19.  *
  20.  *
  21.  *  This file is subject to the terms and conditions of the GNU General Public
  22.  *  License.  See the file COPYING in the main directory of this archive
  23.  *  for more details.
  24.  *
  25.  *  History:
  26.  *    26 Feb 1998 Added support for booting APUS systems.
  27.  *    27 Mar 1997 FPU-less machines couldn't boot kernels that use bootinfo
  28.  *            interface version 1.0 (Geert)
  29.  *    03 Feb 1997 Implemented kernel decompression (Geert, based on Roman's
  30.  *            code for ataboot)
  31.  *    30 Dec 1996 Reverted the CPU detection to the old scheme
  32.  *            New boot parameter override scheme (Geert)
  33.  *      27 Nov 1996 Compatibility with bootinfo interface version 1.0 (Geert)
  34.  *       9 Sep 1996 Rewritten option parsing
  35.  *            New parameter passing to linuxboot() (linuxboot_args)
  36.  *            (Geert)
  37.  *    18 Aug 1996 Updated for the new boot information structure (Geert)
  38.  *    10 Jan 1996 The real Linux/m68k boot code moved to linuxboot.[ch]
  39.  *            (Geert)
  40.  *    11 Jul 1995 Support for ELF kernel (untested!) (Andreas)
  41.  *     7 Mar 1995 Memory block sizes are rounded to a multiple of 256K
  42.  *            instead of 1M (Geert)
  43.  *    31 May 1994 Memory thrash problem solved (Geert)
  44.  *    11 May 1994 A3640 MapROM check (Geert)
  45.  */
  46.  
  47.  
  48. #ifndef __GNUC__
  49. #error GNU CC is required to compile this program
  50. #endif /* __GNUC__ */
  51.  
  52.  
  53. #define BOOTINFO_COMPAT_1_0    /* bootinfo interface version 1.0 compatible */
  54. /* support compressed kernels? */
  55. #define ZKERNEL
  56.  
  57. #include <stddef.h>
  58. #include <string.h>
  59. #include <errno.h>
  60. #include <sys/types.h>
  61.  
  62. #include <linux/a.out.h>
  63. #include <linux/elf.h>
  64. #include <linux/linkage.h>
  65. #include <asm/bootinfo.h>
  66. #include <asm/amigahw.h>
  67. #include <asm/page.h>
  68.  
  69. #include "linuxboot.h"
  70.  
  71. #define APUS
  72. #ifdef APUS
  73.  
  74. #define INTUITION_CLASSES_H 1
  75.  
  76. #include <powerup/ppclib/interface.h>
  77. /*#include <powerup/gcclib/powerup_protos.h>*/
  78. #include <powerup/ppclib/message.h>
  79. #include <powerup/ppclib/tasks.h>
  80.  
  81. #endif
  82.  
  83. #undef custom
  84. #define custom ((*(volatile struct CUSTOM *)(CUSTOM_PHYSADDR)))
  85.  
  86. /* temporary stack size */
  87. #define TEMP_STACKSIZE    (256)
  88.  
  89. #define DEFAULT_BAUD    (9600)
  90.  
  91. extern char copyall, copyallend;
  92.  
  93. extern char getvbr, wedgie;
  94.  
  95. static struct exec kexec;
  96. static Elf32_Ehdr kexec_elf;
  97. static const struct linuxboot_args *linuxboot_args;
  98.  
  99. /* Bootinfo */
  100. struct amiga_bootinfo bi;
  101.  
  102. #ifdef BOOTINFO_COMPAT_1_0
  103. static struct compat_bootinfo compat_bootinfo;
  104. #endif /* BOOTINFO_COMPAT_1_0 */
  105.  
  106. #define MAX_BI_SIZE    (4096)
  107. static u_long bi_size;
  108. static union {
  109.     struct bi_record record;
  110.     u_char fake[MAX_BI_SIZE];
  111. } bi_union;
  112.  
  113. #define kernelname    linuxboot_args->kernelname
  114. #define ramdiskname    linuxboot_args->ramdiskname
  115. #define debugflag    linuxboot_args->debugflag
  116. #define keep_video    linuxboot_args->keep_video
  117. #define reset_boards    linuxboot_args->reset_boards
  118. #define baud        linuxboot_args->baud
  119.  
  120. #define apus_boot    linuxboot_args->apus_boot
  121. #define checksum    linuxboot_args->checksum
  122.  
  123. #define Puts        linuxboot_args->puts
  124. #define GetChar        linuxboot_args->getchar
  125. #define PutChar        linuxboot_args->putchar
  126. #define Printf        linuxboot_args->printf
  127. #define Open        linuxboot_args->open
  128. #define Seek        linuxboot_args->seek
  129. #define Read        linuxboot_args->read
  130. #define Close        linuxboot_args->close
  131. #define FileSize    linuxboot_args->filesize
  132. #define Sleep        linuxboot_args->sleep
  133.  
  134.     /*
  135.      *  Function Prototypes
  136.      */
  137.  
  138. static u_long get_chipset(void);
  139. static void get_processor(u_long *cpu, u_long *fpu, u_long *mmu);
  140. static u_long get_model(u_long chipset);
  141. static int probe_resident(const char *name);
  142. static int probe_resource(const char *name);
  143. static int create_bootinfo(void);
  144. #ifdef BOOTINFO_COMPAT_1_0
  145. static int create_compat_bootinfo(void);
  146. #endif /* BOOTINFO_COMPAT_1_0 */
  147. static int add_bi_record(u_short tag, u_short size, const void *data);
  148. static int add_bi_string(u_short tag, const u_char *s);
  149. static int check_bootinfo_version(const char *memptr);
  150. static void start_kernel(void (*startfunc)(), char *stackp, char *memptr,
  151.              u_long start_mem, u_long mem_size, u_long rd_size,
  152.              u_long kernel_size) __attribute__ ((noreturn));
  153. asmlinkage u_long maprommed(void);
  154. asmlinkage u_long check346(void);
  155. #ifdef ZKERNEL
  156. static int load_zkernel(int fd);
  157. static int KRead(int fd, void *buf, int cnt);
  158. static int KSeek(int fd, int offset);
  159. static int KClose(int fd);
  160. #else
  161. #define KRead        Read
  162. #define KSeek        Seek
  163. #define KClose        Close
  164. #endif
  165.  
  166.  
  167.     /*
  168.      *    Reset functions for nasty Zorro boards
  169.      */
  170.  
  171. static void reset_rb3(const struct ConfigDev *cd);
  172. static void reset_piccolo(const struct ConfigDev *cd);
  173. static void reset_sd64(const struct ConfigDev *cd);
  174. static void reset_a2065(const struct ConfigDev *cd);
  175. static void reset_ariadne(const struct ConfigDev *cd);
  176. static void reset_hydra(const struct ConfigDev *cd);
  177. #if 0
  178. static void reset_a2060(const struct ConfigDev *cd);
  179. #endif
  180.  
  181. struct boardreset {
  182.     u_short manuf;
  183.     u_short prod;
  184.     const char *name;
  185.     void (*reset)(const struct ConfigDev *cd);
  186. };
  187.  
  188. static struct boardreset boardresetdb[] = {
  189.     { MANUF_HELFRICH1, PROD_RAINBOW3, "Rainbow 3", reset_rb3 },
  190.     { MANUF_HELFRICH2, PROD_PICCOLO_REG, "Piccolo", reset_piccolo },
  191.     { MANUF_HELFRICH2, PROD_SD64_REG, "SD64", reset_sd64 },
  192.     { MANUF_COMMODORE, PROD_A2065, "A2065", reset_a2065 },
  193.     { MANUF_VILLAGE_TRONIC, PROD_ARIADNE, "Ariadne", reset_ariadne },
  194.     { MANUF_HYDRA_SYSTEMS, PROD_AMIGANET, "Hydra", reset_hydra },
  195. #if 0
  196.     { MANUF_COMMODORE, PROD_A2060, "A2060", reset_a2060 },
  197. #endif
  198. };
  199. #define NUM_BOARDRESET    sizeof(boardresetdb)/sizeof(*boardresetdb)
  200.  
  201. static void (*boardresetfuncs[ZORRO_NUM_AUTO])(const struct ConfigDev *cd);
  202.  
  203.  
  204. const char *amiga_models[] = {
  205.     "Amiga 500", "Amiga 500+", "Amiga 600", "Amiga 1000", "Amiga 1200",
  206.     "Amiga 2000", "Amiga 2500", "Amiga 3000", "Amiga 3000T", "Amiga 3000+",
  207.     "Amiga 4000", "Amiga 4000T", "CDTV", "CD32", "Draco"
  208. };
  209. const u_long first_amiga_model = AMI_500;
  210. const u_long last_amiga_model = AMI_DRACO;
  211.  
  212.  
  213. #define MASK(model)    (1<<AMI_##model)
  214.  
  215. #define CLASS_A3000    (MASK(3000) | MASK(3000T))
  216. #define CLASS_A4000    (MASK(4000) | MASK(4000T))
  217. #define CLASS_ZKICK    (MASK(500) | MASK(1000) | MASK(2000) | MASK(2500))
  218.  
  219.  
  220.     /*
  221.      *    Boot the Linux/m68k Operating System
  222.      */
  223.  
  224. u_long linuxboot(const struct linuxboot_args *args)
  225. {
  226.     int kfd = -1, rfd = -1, elf_kernel = 0, do_fast, do_chip;
  227.     int i, j;
  228.     const struct MemHeader *mnp;
  229.     struct ConfigDev *cdp = NULL;
  230.     char *memptr = NULL;
  231.     u_long *stack = NULL;
  232.     u_long fast_total, model_mask, startcodesize, start_mem, mem_size, rd_size;
  233.     u_long kernel_size;
  234.     u_int realbaud;
  235.     u_long memreq = 0, text_offset = 0;
  236.     Elf32_Phdr *kernel_phdrs = NULL;
  237.     void (*startfunc)(void);
  238.     u_short manuf;
  239.     u_char prod;
  240.     void *bi_ptr;
  241.     unsigned long* info;
  242.     struct ConfigDev *zdevs[ZORRO_NUM_AUTO];
  243.  
  244.     linuxboot_args = args;
  245.  
  246.     /* print the greet message */
  247.     Puts("\nLinux/m68k Amiga Bootstrap version " AMIBOOT_VERSION "\n");
  248.     Puts("Copyright 1993,1994 by Hamish Macdonald and Greg Harp\n\n");
  249.  
  250.     /* Note: Initial values in bi override detected values */
  251.     bi = args->bi;
  252.  
  253.     /* machine is Amiga */
  254.     bi.machtype = MACH_AMIGA;
  255.  
  256.     /* determine chipset */
  257.     if (!bi.chipset)
  258.     bi.chipset = get_chipset();
  259.  
  260.     /* determine CPU, FPU and MMU type */
  261.     if (!bi.cputype)
  262.     get_processor(&bi.cputype, &bi.fputype, &bi.mmutype);
  263.  
  264.     /* determine Amiga model */
  265.     if (!bi.model)
  266.     bi.model = get_model(bi.chipset);
  267.     model_mask = (bi.model != AMI_UNKNOWN) ? 1<<bi.model : 0;
  268.  
  269.     /* Memory & AutoConfig based on 'unix_boot.c' by C= */
  270.  
  271.     /* find all of the autoconfig boards in the system */
  272.     if (!bi.num_autocon)
  273.     for (i = 0; (cdp = (struct ConfigDev *)FindConfigDev(cdp, -1, -1)); i++)
  274.         if (bi.num_autocon < ZORRO_NUM_AUTO) {
  275.         zdevs[i] = cdp;
  276.         /* copy the contents of each structure into our boot info and
  277.            count this device */
  278.         memcpy(&bi.autocon[bi.num_autocon++], cdp,
  279.                sizeof(struct ConfigDev));
  280.         } else
  281.         Printf("Warning: too many AutoConfig devices. Ignoring device "
  282.                "at 0x%08lx\n", cdp->cd_BoardAddr);
  283.  
  284.     do_fast = bi.num_memory ? 0 : 1;
  285.     do_chip = bi.chip_size ? 0 : 1;
  286.     /* find out the memory in the system */
  287.     for (mnp = (struct MemHeader *)SysBase->MemList.lh_Head;
  288.      mnp->mh_Node.ln_Succ;
  289.      mnp = (struct MemHeader *)mnp->mh_Node.ln_Succ) {
  290.     struct MemHeader mh;
  291.  
  292.     /* copy the information */
  293.     mh = *mnp;
  294.  
  295.     /* skip virtual memory */
  296.     if (!(mh.mh_Attributes & MEMF_PUBLIC))
  297.         continue;
  298.  
  299.     /* if we suspect that Kickstart is shadowed in an A3000,
  300.        modify the entry to show 512K more at the top of RAM
  301.        Check first for a MapROMmed A3640 board: overwriting the
  302.        Kickstart image causes an infinite lock-up on reboot! */
  303.     if ((mh.mh_Upper == (void *)0x07f80000) &&
  304.         (model_mask & (CLASS_A3000 | CLASS_A4000)))
  305.         if ((bi.cputype & CPU_68040) && Supervisor(maprommed))
  306.         Puts("A3640 MapROM detected.\n");
  307.         else if (model_mask & CLASS_A3000) {
  308.         mh.mh_Upper = (void *)0x08000000;
  309.         Puts("A3000 shadowed Kickstart detected.\n");
  310.         }
  311.  
  312.     /* if we suspect that Kickstart is zkicked,
  313.        modify the entry to show 512K more at the botton of RAM */
  314.     if ((mh.mh_Lower == (void *)0x00280020) &&
  315.         (model_mask & CLASS_ZKICK)) {
  316.         mh.mh_Lower = (void *)0x00200000;
  317.         Puts("ZKick detected.\n");
  318.     }
  319.  
  320.     /* mask the memory limit values */
  321.     mh.mh_Upper = (void *)((u_long)mh.mh_Upper & 0xfffff000);
  322.     mh.mh_Lower = (void *)((u_long)mh.mh_Lower & 0xfffff000);
  323.  
  324.     /* if fast memory */
  325.     if (do_fast && mh.mh_Attributes & MEMF_FAST) {
  326.         /* set the size value to the size of this block and mask off to a
  327.            256K increment */
  328.         u_long size = ((u_long)mh.mh_Upper-(u_long)mh.mh_Lower)&0xfffc0000;
  329.         if (size > 0)
  330.         if (bi.num_memory < NUM_MEMINFO) {
  331.             /* record the start and size */
  332.             bi.memory[bi.num_memory].addr = (u_long)mh.mh_Lower;
  333.             bi.memory[bi.num_memory].size = size;
  334.             /* count this block */
  335.             bi.num_memory++;
  336.         } else
  337.             Printf("Warning: too many memory blocks. Ignoring block "
  338.                    "of %ldK at 0x%08x\n", size>>10,
  339.                (u_long)mh.mh_Lower);
  340.     } else if (do_chip && mh.mh_Attributes & MEMF_CHIP)
  341.         /* if CHIP memory, record the size */
  342.         bi.chip_size = (u_long)mh.mh_Upper;
  343.     }
  344.  
  345.     /* get info from ExecBase */
  346.     if (!bi.vblank)
  347.     bi.vblank = SysBase->VBlankFrequency;
  348.     if (!bi.psfreq)
  349.     bi.psfreq = SysBase->PowerSupplyFrequency;
  350.     if (!bi.eclock)
  351.     bi.eclock = SysBase->ex_EClockFrequency;
  352.  
  353.     /* serial port */
  354.     if (!bi.serper) {
  355.     realbaud = baud ? baud : DEFAULT_BAUD;
  356.     bi.serper = (5*bi.eclock+realbaud/2)/realbaud-1;
  357.     }
  358.  
  359.     /* display Amiga model */
  360.     if (bi.model >= first_amiga_model && bi.model <= last_amiga_model)
  361.     Printf("%s ", amiga_models[bi.model-first_amiga_model]);
  362.     else
  363.     Puts("Amiga ");
  364.  
  365.     /* display the CPU type */
  366.     Puts("CPU: ");
  367.     switch (bi.cputype) {
  368.     case CPU_68020:
  369.         Puts("68020 (Do you have an MMU?)");
  370.         break;
  371.     case CPU_68030:
  372.         Puts("68030");
  373.         break;
  374.     case CPU_68040:
  375.         Puts("68040");
  376.         break;
  377.     case CPU_68060:
  378.         Puts("68060");
  379.         break;
  380.     default:
  381.         Puts("Insufficient for Linux.  Aborting...\n");
  382.         Printf("SysBase->AttnFlags = 0x%08lx\n", SysBase->AttnFlags);
  383.         goto Fail;
  384.     }
  385.     switch (bi.fputype) {
  386.     case FPU_68881:
  387.         Puts(" with 68881 FPU");
  388.         break;
  389.     case FPU_68882:
  390.         Puts(" with 68882 FPU");
  391.         break;
  392.     case FPU_68040:
  393.     case FPU_68060:
  394.         Puts(" with internal FPU");
  395.         break;
  396.     default:
  397.         Puts(" without FPU");
  398.         break;
  399.     }
  400.  
  401.     /* display the chipset */
  402.     switch (bi.chipset) {
  403.     case CS_STONEAGE:
  404.         Puts(", old or unknown chipset");
  405.         break;
  406.     case CS_OCS:
  407.         Puts(", OCS");
  408.         break;
  409.     case CS_ECS:
  410.         Puts(", ECS");
  411.         break;
  412.     case CS_AGA:
  413.         Puts(", AGA chipset");
  414.         break;
  415.     }
  416.  
  417.     Puts("\n\n");
  418.  
  419.     /* display the command line */
  420.     Printf("Command line is '%s'\n", bi.command_line);
  421.  
  422.     /* display the clock statistics */
  423.     Printf("Vertical Blank Frequency: %ldHz\n", bi.vblank);
  424.     Printf("Power Supply Frequency: %ldHz\n", bi.psfreq);
  425.     Printf("EClock Frequency: %ldHz\n\n", bi.eclock);
  426.  
  427.     /* display autoconfig devices */
  428.     if (bi.num_autocon) {
  429.     Printf("Found %ld AutoConfig Device%s\n", bi.num_autocon,
  430.            bi.num_autocon > 1 ? "s" : "");
  431.     for (i = 0; i < bi.num_autocon; i++) {
  432.         Printf("Device %ld: addr = 0x%08lx", i,
  433.            (u_long)zdevs[i]->cd_BoardAddr);
  434.         boardresetfuncs[i] = NULL;
  435.         if (reset_boards) {
  436.         manuf = zdevs[i]->cd_Rom.er_Manufacturer;
  437.         prod = zdevs[i]->cd_Rom.er_Product;
  438.         for (j = 0; j < NUM_BOARDRESET; j++)
  439.             if ((manuf == boardresetdb[j].manuf) &&
  440.             (prod == boardresetdb[j].prod)) {
  441.             Printf(" [%s - will be reset at kernel boot time]",
  442.                    boardresetdb[j].name);
  443.             boardresetfuncs[i] = boardresetdb[j].reset;
  444.             break;
  445.             }
  446.         }
  447.         PutChar('\n');
  448.     }
  449.     } else
  450.     Puts("No AutoConfig Devices Found\n");
  451.  
  452.     /* display memory */
  453.     if (bi.num_memory) {
  454.     Printf("\nFound %ld Block%sof Memory\n", bi.num_memory,
  455.            bi.num_memory > 1 ? "s " : " ");
  456.     for (i = 0; i < bi.num_memory; i++)
  457.         Printf("Block %ld: 0x%08lx to 0x%08lx (%ldK)\n", i,
  458.            bi.memory[i].addr, bi.memory[i].addr+bi.memory[i].size,
  459.            bi.memory[i].size>>10);
  460.     } else {
  461.     Puts("No memory found?!  Aborting...\n");
  462.     goto Fail;
  463.     }
  464.  
  465.     /* display chip memory size */
  466.     Printf("%ldK of CHIP memory\n", bi.chip_size>>10);
  467.  
  468.     start_mem = bi.memory[0].addr;
  469.     mem_size = bi.memory[0].size;
  470.  
  471.     /* tell us where the kernel will go */
  472.     Printf("\nThe kernel will be located at 0x%08lx\n", start_mem);
  473.  
  474.     /* verify that there is enough Chip RAM */
  475.     if (bi.chip_size < 512*1024) {
  476.     Puts("Not enough Chip RAM in this system.  Aborting...\n");
  477.     goto Fail;
  478.     }
  479.  
  480.     /* verify that there is enough Fast RAM */
  481.     for (fast_total = 0, i = 0; i < bi.num_memory; i++)
  482.     fast_total += bi.memory[i].size;
  483.     if (fast_total < 2*1024*1024) {
  484.     Puts("Not enough Fast RAM in this system.  Aborting...\n");
  485.     goto Fail;
  486.     }
  487.  
  488.     /* support for ramdisk */
  489.     if (ramdiskname) {
  490.     int size;
  491.  
  492.     if ((size = FileSize(ramdiskname)) == -1) {
  493.         Printf("Unable to find size of ramdisk file `%s'\n", ramdiskname);
  494.         goto Fail;
  495.     }
  496.     /* record ramdisk size */
  497.     bi.ramdisk.size = size;
  498.     } else
  499.     bi.ramdisk.size = 0;
  500.     rd_size = bi.ramdisk.size;
  501.     bi.ramdisk.addr = (u_long)start_mem+mem_size-rd_size;
  502.  
  503.     /* create the bootinfo structure */
  504.     if (!create_bootinfo())
  505.     goto Fail;
  506.  
  507.     /* open kernel executable and read exec header */
  508.     if ((kfd = Open(kernelname)) == -1) {
  509.     Printf("Unable to open kernel file `%s'\n", kernelname);
  510.     goto Fail;
  511.     }
  512.     if (KRead(kfd, (void *)&kexec, sizeof(kexec)) != sizeof(kexec)) {
  513.     Puts("Unable to read exec header from kernel file\n");
  514.     goto Fail;
  515.     }
  516.  
  517. #ifdef ZKERNEL
  518.     if (((unsigned char *)&kexec)[0] == 037 &&
  519.     (((unsigned char *)&kexec)[1] == 0213 ||
  520.      ((unsigned char *)&kexec)[1] == 0236)) {
  521.     /* That's a compressed kernel */
  522.     Puts("Kernel is compressed\n");
  523.     if (load_zkernel(kfd)) {
  524.         Puts("Decompression error -- aborting\n");
  525.         goto Fail;
  526.     }
  527.     }
  528. #endif
  529.  
  530.     switch (N_MAGIC(kexec)) {
  531.     case ZMAGIC:
  532.         if (debugflag)
  533.         Puts("\nLoading a.out (ZMAGIC) Linux/m68k kernel...\n");
  534.         text_offset = N_TXTOFF(kexec);
  535.         break;
  536.  
  537.     case QMAGIC:
  538.         if (debugflag)
  539.         Puts("\nLoading a.out (QMAGIC) Linux/m68k kernel...\n");
  540.         text_offset = sizeof(kexec);
  541.         /* the text size includes the exec header; remove this */
  542.         kexec.a_text -= sizeof(kexec);
  543.         break;
  544.  
  545.     default:
  546.         /* Try to parse it as an ELF header */
  547.         KSeek(kfd, 0);
  548.         if ((KRead(kfd, (void *)&kexec_elf, sizeof(kexec_elf)) ==
  549.          sizeof(kexec_elf)) &&
  550.          (memcmp(&kexec_elf.e_ident[EI_MAG0], ELFMAG, SELFMAG) == 0)) {
  551.         elf_kernel = 1;
  552.         if (debugflag)
  553.             Puts("\nLoading ELF Linux/m68k kernel...\n");
  554.         /* A few plausibility checks */
  555.         if ((kexec_elf.e_type != ET_EXEC) ||
  556.             (kexec_elf.e_machine != EM_PPC && apus_boot) ||
  557.             (kexec_elf.e_machine != EM_68K && !apus_boot) ||
  558.             (kexec_elf.e_version != EV_CURRENT)) {
  559.             Puts("Invalid ELF header contents in kernel\n");
  560.             Printf("machine : %d, type: %d, version: %d\n",
  561.              kexec_elf.e_machine, kexec_elf.e_type, kexec_elf.e_version);
  562.             goto Fail;
  563.         }
  564.         /* Load the program headers */
  565.         if (!(kernel_phdrs =
  566.               (Elf32_Phdr *)AllocMem(kexec_elf.e_phnum*sizeof(Elf32_Phdr),
  567.                          MEMF_FAST | MEMF_PUBLIC |
  568.                          MEMF_CLEAR))) {
  569.             Puts("Unable to allocate memory for program headers\n");
  570.             goto Fail;
  571.         }
  572.         KSeek(kfd, kexec_elf.e_phoff);
  573.         if (KRead(kfd, (void *)kernel_phdrs,
  574.              kexec_elf.e_phnum*sizeof(*kernel_phdrs)) !=
  575.             kexec_elf.e_phnum*sizeof(*kernel_phdrs)) {
  576.             Puts("Unable to read program headers from kernel file\n");
  577.             goto Fail;
  578.         }
  579.         break;
  580.         }
  581.         Printf("Wrong magic number 0x%08lx in kernel header\n",
  582.            N_MAGIC(kexec));
  583.         goto Fail;
  584.     }
  585.  
  586.     /* Load the kernel at one page after start of mem */
  587.     if (!apus_boot) {
  588.     start_mem += PAGE_SIZE;
  589.     mem_size -= PAGE_SIZE;
  590.     }
  591.  
  592.     /* Align bss size to multiple of four */
  593.     if (!elf_kernel)
  594.     kexec.a_bss = (kexec.a_bss+3) & ~3;
  595.  
  596.     /* calculate the total required amount of memory */
  597.     if (elf_kernel) {
  598.     u_long min_addr = 0xffffffff, max_addr = 0;
  599.     for (i = 0; i < kexec_elf.e_phnum; i++) {
  600.         if (min_addr > kernel_phdrs[i].p_vaddr)
  601.         min_addr = kernel_phdrs[i].p_vaddr;
  602.         if (max_addr < kernel_phdrs[i].p_vaddr+kernel_phdrs[i].p_memsz)
  603.         max_addr = kernel_phdrs[i].p_vaddr+kernel_phdrs[i].p_memsz;
  604.     }
  605.     /* This is needed for newer linkers that include the header in
  606.        the first segment.  */
  607.     if (apus_boot) {
  608.         /* Avoid ugly hacks further down. */
  609.         kernel_phdrs[0].p_vaddr = PAGE_SIZE;
  610.     } else if (min_addr == 0) {
  611.         min_addr = PAGE_SIZE;
  612.         kernel_phdrs[0].p_vaddr += PAGE_SIZE;
  613.         kernel_phdrs[0].p_offset += PAGE_SIZE;
  614.         kernel_phdrs[0].p_filesz -= PAGE_SIZE;
  615.         kernel_phdrs[0].p_memsz -= PAGE_SIZE;
  616.     }
  617.     kernel_size = max_addr-min_addr;
  618.     } else
  619.     kernel_size = kexec.a_text+kexec.a_data+kexec.a_bss;
  620.     memreq = kernel_size+bi_size+rd_size;
  621. #ifdef BOOTINFO_COMPAT_1_0
  622.     if (sizeof(compat_bootinfo) > bi_size)
  623.     memreq = kernel_size+sizeof(compat_bootinfo)+rd_size;
  624. #endif /* BOOTINFO_COMPAT_1_0 */
  625.     if (!(memptr = (char *)AllocMem(memreq, MEMF_FAST | MEMF_PUBLIC |
  626.                         MEMF_CLEAR))) {
  627.     Puts("Unable to allocate memory\n");
  628.     goto Fail;
  629.     }
  630.  
  631.     /* read the text and data segments from the kernel image */
  632.     if (elf_kernel)
  633.     for (i = 0; i < kexec_elf.e_phnum; i++) {
  634.         if (KSeek(kfd, kernel_phdrs[i].p_offset) == -1) {
  635.         Printf("Failed to seek to segment %ld\n", i);
  636.         goto Fail;
  637.         }
  638.         if (KRead(kfd, memptr+kernel_phdrs[i].p_vaddr-PAGE_SIZE,
  639.               kernel_phdrs[i].p_filesz) != kernel_phdrs[i].p_filesz) {
  640.         Printf("Failed to read segment %ld\n", i);
  641.         goto Fail;
  642.         }
  643.     }
  644.     else {
  645.     if (KSeek(kfd, text_offset) == -1) {
  646.         Puts("Failed to seek to text\n");
  647.         goto Fail;
  648.     }
  649.     if (KRead(kfd, memptr, kexec.a_text) != kexec.a_text) {
  650.         Puts("Failed to read text\n");
  651.         goto Fail;
  652.     }
  653.     /* data follows immediately after text */
  654.     if (KRead(kfd, memptr+kexec.a_text, kexec.a_data) != kexec.a_data) {
  655.         Puts("Failed to read data\n");
  656.         goto Fail;
  657.     }
  658.     }
  659.     KClose(kfd);
  660.     kfd = -1;
  661.  
  662.     /* Check kernel's bootinfo version */
  663.     switch (apus_boot ? BI_VERSION_MAJOR(AMIGA_BOOTI_VERSION) :
  664.         check_bootinfo_version(memptr)) {
  665.     case BI_VERSION_MAJOR(AMIGA_BOOTI_VERSION):
  666.         bi_ptr = &bi_union.record;
  667.         break;
  668.  
  669. #ifdef BOOTINFO_COMPAT_1_0
  670.     case BI_VERSION_MAJOR(COMPAT_AMIGA_BOOTI_VERSION):
  671.         if (!create_compat_bootinfo())
  672.         goto Fail;
  673.         bi_ptr = &compat_bootinfo;
  674.         bi_size = sizeof(compat_bootinfo);
  675.         break;
  676. #endif /* BOOTINFO_COMPAT_1_0 */
  677.  
  678.     default:
  679.         goto Fail;
  680.     }
  681.  
  682.     /* copy the bootinfo to the end of the kernel image */
  683.     memcpy((void *)(memptr+kernel_size), bi_ptr, bi_size);
  684.  
  685.     if (ramdiskname) {
  686.     if ((rfd = Open(ramdiskname)) == -1) {
  687.         Printf("Unable to open ramdisk file `%s'\n", ramdiskname);
  688.         goto Fail;
  689.     }
  690.     if (Read(rfd, memptr+kernel_size+bi_size, rd_size) != rd_size) {
  691.         Puts("Failed to read ramdisk file\n");
  692.         goto Fail;
  693.     }
  694.     Close(rfd);
  695.     rfd = -1;
  696.     }
  697.  
  698.     /* allocate temporary chip ram stack */
  699.     if (!(stack = (u_long *)AllocMem(TEMP_STACKSIZE, MEMF_CHIP | MEMF_CLEAR))) {
  700.     Puts("Unable to allocate memory for stack\n");
  701.     goto Fail;
  702.     }
  703.  
  704.     /* allocate chip ram for copy of startup code */
  705.     startcodesize = ©allend-©all;
  706.     if (!(startfunc = (void (*)(void))AllocMem(startcodesize,
  707.                            MEMF_CHIP | MEMF_CLEAR))) {
  708.     Puts("Unable to allocate memory for startcode\n");
  709.     goto Fail;
  710.     }
  711.  
  712.     /* copy startup code to CHIP RAM */
  713.     memcpy(startfunc, ©all, startcodesize);
  714.  
  715.     if (debugflag) {
  716.     if (bi.ramdisk.size)
  717.         Printf("RAM disk at 0x%08lx, size is %ldK\n",
  718.            (u_long)memptr+kernel_size, bi.ramdisk.size>>10);
  719.  
  720.     if (elf_kernel) {
  721.         PutChar('\n');
  722.         for (i = 0; i < kexec_elf.e_phnum; i++)
  723.         Printf("Kernel segment %ld at 0x%08lx, size %ld\n", i,
  724.                start_mem+kernel_phdrs[i].p_vaddr-PAGE_SIZE,
  725.                kernel_phdrs[i].p_memsz);
  726.         Printf("Boot info        at 0x%08lx\n", start_mem+kernel_size);
  727.     } else {
  728.         Printf("\nKernel text at 0x%08lx, code size 0x%08lx\n", start_mem,
  729.            kexec.a_text);
  730.         Printf("Kernel data at 0x%08lx, data size 0x%08lx\n",
  731.            start_mem+kexec.a_text, kexec.a_data);
  732.         Printf("Kernel bss  at 0x%08lx, bss  size 0x%08lx\n",
  733.            start_mem+kexec.a_text+kexec.a_data, kexec.a_bss);
  734.         Printf("Boot info   at 0x%08lx\n", start_mem+kernel_size);
  735.     }
  736.     Printf("\nKernel entry is 0x%08lx\n", elf_kernel ? kexec_elf.e_entry :
  737.                                kexec.a_entry);
  738.  
  739.     Printf("ramdisk dest top is 0x%08lx\n", start_mem+mem_size);
  740.     Printf("ramdisk lower limit is 0x%08lx\n",
  741.            (u_long)(memptr+kernel_size));
  742.     Printf("ramdisk src top is 0x%08lx\n",
  743.            (u_long)(memptr+kernel_size)+rd_size);
  744.  
  745.     Puts("\nType a key to continue the Linux/m68k boot...");
  746.     GetChar();
  747.     PutChar('\n');
  748.     }
  749.  
  750.     /* wait for things to settle down */
  751.     Sleep(1000000);
  752.  
  753.  
  754.     {
  755.         void* PPCPort;
  756.         void* PPCMsg;
  757.  
  758. #define CHIP_PTR (0xfff00)
  759. #define INFO_SIZE (0x3000 + 0x0100)
  760.     if (apus_boot) {
  761.         /* Let the PowerPC handle the actual kernel start */
  762.     
  763.         /* Store some relevant information about the kernel image
  764.          * and RAM disk at *CHIP_PTR.
  765.          */
  766.         unsigned long boot_msg;
  767.         
  768.         /* Make sure the CHIP_PTR will not be destroyed. */
  769.         if (!AllocAbs (0x10, CHIP_PTR)){
  770.             Puts("Unable to allocate CHIP memory at 0xfff00.\n"
  771.                  "Try booting with a smaller resolution.\n");
  772.         }
  773.         
  774.         if (!(boot_msg = (unsigned long) AllocMem (0x200, 
  775.                                                    MEMF_REVERSE 
  776.                                                    | MEMF_CHIP 
  777.                                                    | MEMF_CLEAR))){
  778.                                                    
  779.             Puts("Unable to allocate CHIP memory for boot message\n");
  780.             goto Fail;
  781.         }
  782.  
  783.         if (!(info = (unsigned long*) AllocMem (INFO_SIZE, 
  784.                                                 MEMF_CHIP | MEMF_CLEAR))){
  785.             Puts("Unable to allocate CHIP memory for info table and"
  786.                  " reloc code\n");
  787.             goto Fail;
  788.         }        
  789.  
  790.         /* Leave the pointer in chip mem at address CHIP_PTR. */
  791.         *((unsigned long*) CHIP_PTR) = (unsigned long) info;
  792.         info[0] = (unsigned long) (memptr+kernel_phdrs[0].p_vaddr-PAGE_SIZE);
  793.         info[1] = start_mem;
  794.         info[2] = kernel_size;
  795.         info[3] = bi_size;
  796.         info[4] = rd_size;
  797.         info[5] = mem_size;
  798.         info[6] = boot_msg + 0x100;
  799.         info[7] = 0; /* checksum */
  800.         info[8] = (unsigned long)info + 0x2000; /* stack */
  801.         
  802.         /* Calculate a simple kernel checksum. */
  803.         if (checksum)
  804.         {
  805.             int i = (info[2] + info[3]) / 4;
  806.             unsigned char* k_p = (unsigned char*) info[0];
  807.             unsigned long kcs = 0;
  808.             
  809.             while (i--)
  810.             {
  811.                 unsigned long w = 0;
  812.                 
  813.                 w |= *k_p++;
  814.                 w <<= 8;
  815.                 w |= *k_p++;
  816.                 w <<= 8;
  817.                 w |= *k_p++;
  818.                 w <<= 8;
  819.                 w |= *k_p++;
  820.  
  821.                 
  822.                 kcs = kcs ^ i;
  823.                 kcs = kcs ^ w;
  824.             }
  825.             info[7] = kcs;
  826.         }
  827.         
  828.         /* Set LVL7 vector ("expose the top rim of our shorts") */
  829.         {
  830.             unsigned long* vbr;
  831.  
  832.             vbr = (unsigned long*) Supervisor((void*)&getvbr);
  833.             vbr[31] = (unsigned long) &wedgie;
  834.         }
  835.         
  836.         
  837.         {
  838.             void* elfObject;
  839.             void* task;
  840.             struct TagItem MyTags[2];
  841.             struct TagItem tag;
  842.             
  843.             /* Load PPC elf object. */
  844.             elfObject = (void*) PPCLoadObject("ram:ppc_boot");
  845.         
  846.             /* Start PPC code, asking for a MSGPORT to be created. */
  847.             MyTags[0].ti_Tag    =    PPCTASKTAG_MSGPORT;
  848.             MyTags[0].ti_Data    =    TRUE;
  849.             MyTags[1].ti_Tag    =    TAG_DONE;
  850.             task = PPCCreateTask(elfObject, MyTags);
  851.  
  852.             tag.ti_Tag = PPCTASKINFOTAG_MSGPORT;
  853.             if (PPCPort=(void*) PPCGetTaskAttrs(task, &tag))
  854.             {
  855.                 PPCMsg = PPCCreateMessage(NULL, 0);
  856.             }
  857.  
  858.             
  859.             if (PPCPort == 0 || PPCMsg == 0)
  860.             {
  861.                 Puts ("Didn't get contact with PPC task...\n");
  862.                 goto Fail;
  863.             }
  864.         }
  865.     }
  866.  
  867.     /* turn off caches */
  868.     CacheControl(0, ~0);
  869.     
  870.     if (!keep_video)
  871.     /* set graphics mode to a nice normal one */
  872.     LoadView(NULL);
  873.  
  874.     /* reset nasty Zorro boards */
  875.     if (reset_boards)
  876.     for (i = 0; i < bi.num_autocon; i++)
  877.         if (boardresetfuncs[i])
  878.             boardresetfuncs[i](zdevs[i]);
  879.  
  880.     if (apus_boot && PPCPort && PPCMsg)
  881.     {
  882.         /* Notify the PPC that we are done ("bend over") */
  883.         PPCSendMessage(PPCPort, PPCMsg,    NULL, 0, 0);
  884.         for (;;) ;
  885.     }
  886.  
  887.     /* Go into supervisor state */
  888.     SuperState();
  889.  
  890.     }
  891.     /* Turn off interrupts. */
  892.     Disable();
  893.  
  894.     /* Turn off all DMA */
  895.     custom.dmacon = DMAF_ALL | DMAF_MASTER;
  896.     
  897.     /* turn off any mmu translation */
  898.     disable_mmu();
  899.  
  900.     /* execute the copy-and-go code (from CHIP RAM) */
  901.     start_kernel(startfunc, (char *)stack+TEMP_STACKSIZE, memptr, start_mem,
  902.          mem_size, rd_size, kernel_size);
  903.  
  904.     /* Clean up and exit in case of a failure */
  905. Fail:
  906.     if (kfd != -1)
  907.     KClose(kfd);
  908.     if (rfd != -1)
  909.     Close(rfd);
  910.     if (info)
  911.     FreeMem((void *) info, INFO_SIZE);
  912.     if (memptr)
  913.     FreeMem((void *)memptr, memreq);
  914.     if (stack)
  915.     FreeMem((void *)stack, TEMP_STACKSIZE);
  916.     if (kernel_phdrs)
  917.     FreeMem((void *)kernel_phdrs, kexec_elf.e_phnum*sizeof(Elf32_Phdr));
  918.     return(FALSE);
  919. }
  920.  
  921.  
  922.     /*
  923.      *    Determine the Chipset
  924.      */
  925.  
  926. static u_long get_chipset(void)
  927. {
  928.     u_char cs;
  929.     u_long chipset;
  930.  
  931.     if (GfxBase->Version >= 39)
  932.     cs = SetChipRev(SETCHIPREV_BEST);
  933.     else
  934.     cs = GfxBase->ChipRevBits0;
  935.     if ((cs & GFXG_AGA) == GFXG_AGA)
  936.     chipset = CS_AGA;
  937.     else if ((cs & GFXG_ECS) == GFXG_ECS)
  938.     chipset = CS_ECS;
  939.     else if ((cs & GFXG_OCS) == GFXG_OCS)
  940.     chipset = CS_OCS;
  941.     else
  942.     chipset = CS_STONEAGE;
  943.     return(chipset);
  944. }
  945.  
  946.  
  947.     /*
  948.      *    Determine the CPU Type
  949.      */
  950.  
  951. static void get_processor(u_long *cpu, u_long *fpu, u_long *mmu)
  952. {
  953.     *cpu = *fpu = 0;
  954.  
  955.     if (SysBase->AttnFlags & AFF_68060)
  956.     *cpu = CPU_68060;
  957.     else if (SysBase->AttnFlags & AFF_68040)
  958.     *cpu = CPU_68040;
  959.     else if (SysBase->AttnFlags & AFF_68030)
  960.     *cpu = CPU_68030;
  961.     else if (SysBase->AttnFlags & AFF_68020)
  962.     *cpu = CPU_68020;
  963.  
  964.     if (*cpu == CPU_68040 || *cpu == CPU_68060) {
  965.     if (SysBase->AttnFlags & AFF_FPU40)
  966.         *fpu = *cpu;
  967.     } else if (SysBase->AttnFlags & AFF_68882)
  968.     *fpu = FPU_68882;
  969.     else if (SysBase->AttnFlags & AFF_68881)
  970.     *fpu = FPU_68881;
  971.  
  972.     *mmu = *cpu;
  973. }
  974.  
  975.     /*
  976.      *    Determine the Amiga Model
  977.      */
  978.  
  979. static u_long get_model(u_long chipset)
  980. {
  981.     u_long model = AMI_UNKNOWN;
  982.  
  983.     if (debugflag)
  984.     Puts("Amiga model identification:\n");
  985.     if (probe_resource("draco.resource"))
  986.     model = AMI_DRACO;
  987.     else {
  988.     if (debugflag)
  989.         Puts("    Chipset: ");
  990.     switch (chipset) {
  991.         case CS_STONEAGE:
  992.         if (debugflag)
  993.             Puts("Old or unknown\n");
  994.         goto OCS;
  995.         break;
  996.  
  997.         case CS_OCS:
  998.         if (debugflag)
  999.             Puts("OCS\n");
  1000. OCS:        if (probe_resident("cd.device"))
  1001.             model = AMI_CDTV;
  1002.         else
  1003.             /* let's call it an A2000 (may be A500, A1000, A2500) */
  1004.             model = AMI_2000;
  1005.         break;
  1006.  
  1007.         case CS_ECS:
  1008.         if (debugflag)
  1009.             Puts("ECS\n");
  1010.         if (probe_resident("Magic 36.7") ||
  1011.             probe_resident("kickad 36.57") ||
  1012.             probe_resident("A3000 Bonus") ||
  1013.             probe_resident("A3000 bonus"))
  1014.             /* let's call it an A3000 (may be A3000T) */
  1015.             model = AMI_3000;
  1016.         else if (probe_resource("card.resource"))
  1017.             model = AMI_600;
  1018.         else
  1019.             /* let's call it an A2000 (may be A500[+], A1000, A2500) */
  1020.             model = AMI_2000;
  1021.         break;
  1022.  
  1023.         case CS_AGA:
  1024.         if (debugflag)
  1025.             Puts("AGA\n");
  1026.         if (probe_resident("A1000 Bonus") ||
  1027.             probe_resident("A4000 bonus"))
  1028.             model = probe_resident("NCR scsi.device") ? AMI_4000T :
  1029.                                 AMI_4000;
  1030.         else if (probe_resource("card.resource"))
  1031.             model = AMI_1200;
  1032.         else if (probe_resident("cd.device"))
  1033.             model = AMI_CD32;
  1034.         else
  1035.             model = AMI_3000PLUS;
  1036.         break;
  1037.     }
  1038.     }
  1039.     if (debugflag) {
  1040.     Puts("\nType a key to continue...");
  1041.     GetChar();
  1042.     Puts("\n\n");
  1043.     }
  1044.     return(model);
  1045. }
  1046.  
  1047.  
  1048.     /*
  1049.      *    Probe for a Resident Modules
  1050.      */
  1051.  
  1052. static int probe_resident(const char *name)
  1053. {
  1054.     const struct Resident *res;
  1055.  
  1056.     if (debugflag)
  1057.     Printf("    Module `%s': ", name);
  1058.     res = FindResident(name);
  1059.     if (debugflag)
  1060.     if (res)
  1061.         Printf("0x%08lx\n", res);
  1062.     else
  1063.         Puts("not present\n");
  1064.     return(res ? TRUE : FALSE);
  1065. }
  1066.  
  1067.  
  1068.     /*
  1069.      *    Probe for an available Resource
  1070.      */
  1071.  
  1072. static int probe_resource(const char *name)
  1073. {
  1074.     const void *res;
  1075.  
  1076.     if (debugflag)
  1077.     Printf("    Resource `%s': ", name);
  1078.     res = OpenResource(name);
  1079.     if (debugflag)
  1080.     if (res)
  1081.         Printf("0x%08lx\n", res);
  1082.     else
  1083.         Puts("not present\n");
  1084.     return(res ? TRUE : FALSE);
  1085. }
  1086.  
  1087.  
  1088.     /*
  1089.      *  Create the Bootinfo structure
  1090.      */
  1091.  
  1092. static int create_bootinfo(void)
  1093. {
  1094.     int i;
  1095.     struct bi_record *record;
  1096.  
  1097.     /* Initialization */
  1098.     bi_size = 0;
  1099.  
  1100.     /* Generic tags */
  1101.     if (!add_bi_record(BI_MACHTYPE, sizeof(bi.machtype), &bi.machtype))
  1102.     return(0);
  1103.     if (!add_bi_record(BI_CPUTYPE, sizeof(bi.cputype), &bi.cputype))
  1104.     return(0);
  1105.     if (!add_bi_record(BI_FPUTYPE, sizeof(bi.fputype), &bi.fputype))
  1106.     return(0);
  1107.     if (!add_bi_record(BI_MMUTYPE, sizeof(bi.mmutype), &bi.mmutype))
  1108.     return(0);
  1109.     for (i = 0; i < bi.num_memory; i++)
  1110.     if (!add_bi_record(BI_MEMCHUNK, sizeof(bi.memory[i]), &bi.memory[i]))
  1111.         return(0);
  1112.     if (bi.ramdisk.size)
  1113.     if (!add_bi_record(BI_RAMDISK, sizeof(bi.ramdisk), &bi.ramdisk))
  1114.         return(0);
  1115.     if (!add_bi_string(BI_COMMAND_LINE, bi.command_line))
  1116.     return(0);
  1117.  
  1118.     /* Amiga tags */
  1119.     if (!add_bi_record(BI_AMIGA_MODEL, sizeof(bi.model), &bi.model))
  1120.     return(0);
  1121.     for (i = 0; i < bi.num_autocon; i++)
  1122.     if (!add_bi_record(BI_AMIGA_AUTOCON, sizeof(bi.autocon[i]),
  1123.                 &bi.autocon[i]))
  1124.         return(0);
  1125.     if (!add_bi_record(BI_AMIGA_CHIP_SIZE, sizeof(bi.chip_size), &bi.chip_size))
  1126.     return(0);
  1127.     if (!add_bi_record(BI_AMIGA_VBLANK, sizeof(bi.vblank), &bi.vblank))
  1128.     return(0);
  1129.     if (!add_bi_record(BI_AMIGA_PSFREQ, sizeof(bi.psfreq), &bi.psfreq))
  1130.     return(0);
  1131.     if (!add_bi_record(BI_AMIGA_ECLOCK, sizeof(bi.eclock), &bi.eclock))
  1132.     return(0);
  1133.     if (!add_bi_record(BI_AMIGA_CHIPSET, sizeof(bi.chipset), &bi.chipset))
  1134.     return(0);
  1135.     if (!add_bi_record(BI_AMIGA_SERPER, sizeof(bi.serper), &bi.serper))
  1136.     return(0);
  1137.  
  1138.     /* Trailer */
  1139.     record = (struct bi_record *)((u_long)&bi_union.record+bi_size);
  1140.     record->tag = BI_LAST;
  1141.     bi_size += sizeof(bi_union.record.tag);
  1142.  
  1143.     return(1);
  1144. }
  1145.  
  1146.  
  1147.     /*
  1148.      *  Add a Record to the Bootinfo Structure
  1149.      */
  1150.  
  1151. static int add_bi_record(u_short tag, u_short size, const void *data)
  1152. {
  1153.     struct bi_record *record;
  1154.     u_int size2;
  1155.  
  1156.     size2 = (sizeof(struct bi_record)+size+3)&-4;
  1157.     if (bi_size+size2+sizeof(bi_union.record.tag) > MAX_BI_SIZE) {
  1158.     Puts("Can't add bootinfo record. Ask a wizard to enlarge me.\n");
  1159.     return(0);
  1160.     }
  1161.     record = (struct bi_record *)((u_long)&bi_union.record+bi_size);
  1162.     record->tag = tag;
  1163.     record->size = size2;
  1164.     memcpy(record->data, data, size);
  1165.     bi_size += size2;
  1166.     return(1);
  1167. }
  1168.  
  1169.  
  1170.     /*
  1171.      *  Add a String Record to the Bootinfo Structure
  1172.      */
  1173.  
  1174. static int add_bi_string(u_short tag, const u_char *s)
  1175. {
  1176.     return(add_bi_record(tag, strlen(s)+1, (void *)s));
  1177. }
  1178.  
  1179.  
  1180. #ifdef BOOTINFO_COMPAT_1_0
  1181.  
  1182.     /*
  1183.      *  Create the Bootinfo structure for backwards compatibility mode
  1184.      */
  1185.  
  1186. static int create_compat_bootinfo(void)
  1187. {
  1188.     u_int i;
  1189.  
  1190.     compat_bootinfo.machtype = bi.machtype;
  1191.     if (bi.cputype & CPU_68020)
  1192.     compat_bootinfo.cputype = COMPAT_CPU_68020;
  1193.     else if (bi.cputype & CPU_68030)
  1194.     compat_bootinfo.cputype = COMPAT_CPU_68030;
  1195.     else if (bi.cputype & CPU_68040)
  1196.     compat_bootinfo.cputype = COMPAT_CPU_68040;
  1197.     else if (bi.cputype & CPU_68060)
  1198.     compat_bootinfo.cputype = COMPAT_CPU_68060;
  1199.     else {
  1200.     Printf("CPU type 0x%08lx not supported by kernel\n", bi.cputype);
  1201.     return(0);
  1202.     }
  1203.     if (bi.fputype & FPU_68881)
  1204.     compat_bootinfo.cputype |= COMPAT_FPU_68881;
  1205.     else if (bi.fputype & FPU_68882)
  1206.     compat_bootinfo.cputype |= COMPAT_FPU_68882;
  1207.     else if (bi.fputype & FPU_68040)
  1208.     compat_bootinfo.cputype |= COMPAT_FPU_68040;
  1209.     else if (bi.fputype & FPU_68060)
  1210.     compat_bootinfo.cputype |= COMPAT_FPU_68060;
  1211.     else if (bi.fputype) {
  1212.     Printf("FPU type 0x%08lx not supported by kernel\n", bi.fputype);
  1213.     return(0);
  1214.     }
  1215.     compat_bootinfo.num_memory = bi.num_memory;
  1216.     if (compat_bootinfo.num_memory > COMPAT_NUM_MEMINFO) {
  1217.     Printf("Warning: using only %ld blocks of memory\n",
  1218.            COMPAT_NUM_MEMINFO);
  1219.     compat_bootinfo.num_memory = COMPAT_NUM_MEMINFO;
  1220.     }
  1221.     for (i = 0; i < compat_bootinfo.num_memory; i++) {
  1222.     compat_bootinfo.memory[i].addr = bi.memory[i].addr;
  1223.     compat_bootinfo.memory[i].size = bi.memory[i].size;
  1224.     }
  1225.     if (bi.ramdisk.size) {
  1226.     compat_bootinfo.ramdisk_size = (bi.ramdisk.size+1023)/1024;
  1227.     compat_bootinfo.ramdisk_addr = bi.ramdisk.addr;
  1228.     } else {
  1229.     compat_bootinfo.ramdisk_size = 0;
  1230.     compat_bootinfo.ramdisk_addr = 0;
  1231.     }
  1232.     strncpy(compat_bootinfo.command_line, bi.command_line, COMPAT_CL_SIZE);
  1233.     compat_bootinfo.command_line[COMPAT_CL_SIZE-1] = '\0';
  1234.  
  1235.     compat_bootinfo.bi_amiga.model = bi.model;
  1236.     compat_bootinfo.bi_amiga.num_autocon = bi.num_autocon;
  1237.     if (compat_bootinfo.bi_amiga.num_autocon > COMPAT_NUM_AUTO) {
  1238.     Printf("Warning: using only %ld AutoConfig devices\n",
  1239.            COMPAT_NUM_AUTO);
  1240.     compat_bootinfo.bi_amiga.num_autocon = COMPAT_NUM_AUTO;
  1241.     }
  1242.     for (i = 0; i < compat_bootinfo.bi_amiga.num_autocon; i++)
  1243.     compat_bootinfo.bi_amiga.autocon[i] = bi.autocon[i];
  1244.     compat_bootinfo.bi_amiga.chip_size = bi.chip_size;
  1245.     compat_bootinfo.bi_amiga.vblank = bi.vblank;
  1246.     compat_bootinfo.bi_amiga.psfreq = bi.psfreq;
  1247.     compat_bootinfo.bi_amiga.eclock = bi.eclock;
  1248.     compat_bootinfo.bi_amiga.chipset = bi.chipset;
  1249.     compat_bootinfo.bi_amiga.hw_present = 0;
  1250.     return(1);
  1251. }
  1252. #endif /* BOOTINFO_COMPAT_1_0 */
  1253.  
  1254.  
  1255.     /*
  1256.      *  Compare the Bootstrap and Kernel Versions
  1257.      */
  1258.  
  1259. static int check_bootinfo_version(const char *memptr)
  1260. {
  1261.     const struct bootversion *bv = (struct bootversion *)memptr;
  1262.     unsigned long version = 0;
  1263.     int i, kernel_major, kernel_minor, boots_major, boots_minor;
  1264.  
  1265.     if (bv->magic == BOOTINFOV_MAGIC)
  1266.     for (i = 0; bv->machversions[i].machtype != 0; ++i)
  1267.         if (bv->machversions[i].machtype == MACH_AMIGA) {
  1268.         version = bv->machversions[i].version;
  1269.         break;
  1270.         }
  1271.     if (!version)
  1272.     Puts("Kernel has no bootinfo version info, assuming 0.0\n");
  1273.  
  1274.     kernel_major = BI_VERSION_MAJOR(version);
  1275.     kernel_minor = BI_VERSION_MINOR(version);
  1276.     boots_major  = BI_VERSION_MAJOR(AMIGA_BOOTI_VERSION);
  1277.     boots_minor  = BI_VERSION_MINOR(AMIGA_BOOTI_VERSION);
  1278.     Printf("Bootstrap's bootinfo version: %ld.%ld\n", boots_major,
  1279.        boots_minor);
  1280.     Printf("Kernel's bootinfo version   : %ld.%ld\n", kernel_major,
  1281.        kernel_minor);
  1282.  
  1283.     switch (kernel_major) {
  1284.     case BI_VERSION_MAJOR(AMIGA_BOOTI_VERSION):
  1285.         if (kernel_minor > boots_minor) {
  1286.         Puts("Warning: Bootinfo version of bootstrap and kernel "
  1287.                "differ!\n");
  1288.         Puts("         Certain features may not work.\n");
  1289.         }
  1290.         break;
  1291.  
  1292. #ifdef BOOTINFO_COMPAT_1_0
  1293.     case BI_VERSION_MAJOR(COMPAT_AMIGA_BOOTI_VERSION):
  1294.         Puts("(using backwards compatibility mode)\n");
  1295.         break;
  1296. #endif /* BOOTINFO_COMPAT_1_0 */
  1297.  
  1298.     default:
  1299.         Printf("\nThis bootstrap is too %s for this kernel!\n",
  1300.            boots_major < kernel_major ? "old" : "new");
  1301.         return(0);
  1302.     }
  1303.     return(kernel_major);
  1304. }
  1305.  
  1306.  
  1307.     /*
  1308.      *    Call the copy-and-go-code
  1309.      */
  1310.  
  1311. static void start_kernel(void (*startfunc)(), char *stackp, char *memptr,
  1312.              u_long start_mem, u_long mem_size, u_long rd_size,
  1313.              u_long kernel_size)
  1314. {
  1315.     register void (*a0)() __asm("a0") = startfunc;
  1316.     register char *a2 __asm("a2") = stackp;
  1317.     register char *a3 __asm("a3") = memptr;
  1318.     register u_long a4 __asm("a4") = start_mem;
  1319.     register u_long d0 __asm("d0") = mem_size;
  1320.     register u_long d1 __asm("d1") = rd_size;
  1321.     register u_long d2 __asm("d2") = kernel_size;
  1322.     register u_long d3 __asm("d3") = bi_size;
  1323.  
  1324.     __asm __volatile ("movel a2,sp;"
  1325.               "jmp a0@"
  1326.               : /* no outputs */
  1327.               : "r" (a0), "r" (a2), "r" (a3), "r" (a4), "r" (d0),
  1328.             "r" (d1), "r" (d2), "r" (d3)
  1329.               /* no return */);
  1330.     /* fake a noreturn */
  1331.     for (;;);
  1332. }
  1333.  
  1334. asm(".text\n"
  1335. ALIGN_STR "\n"
  1336. SYMBOL_NAME_STR(_getvbr) ":
  1337.  movec vbr,d0
  1338.  rte
  1339. ");
  1340.  
  1341.  
  1342. /* LPSTOP cannot be used on the 68060. Apparently the 
  1343.    CyberStorm bus design cannot cope with it.*/
  1344. /* Just let the 68k hang for now. */
  1345. asm(".text\n"
  1346. ALIGN_STR "\n"
  1347. SYMBOL_NAME_STR(_wedgie) ":
  1348. jsr _disable_mmu
  1349. stop #0x2700
  1350. ");
  1351.  
  1352.     /*
  1353.      *    This assembler code is copied to chip ram, and then executed.
  1354.      *    It copies the kernel to it's final resting place.
  1355.      *
  1356.      *    It is called with:
  1357.      *
  1358.      *        a3 = memptr
  1359.      *        a4 = start_mem
  1360.      *        d0 = mem_size
  1361.      *        d1 = rd_size
  1362.      *        d2 = kernel_size
  1363.      *        d3 = bi_size
  1364.      */
  1365.  
  1366. asm(".text\n"
  1367. ALIGN_STR "\n"
  1368. SYMBOL_NAME_STR(_copyall) ":
  1369.                 | /* copy kernel text and data */
  1370.     movel    a3,a0        | src = (u_long *)memptr;
  1371.     movel    a0,a2        | limit = (u_long *)(memptr+kernel_size);
  1372.     addl    d2,a2
  1373.     movel    a4,a1        | dest = (u_long *)start_mem;
  1374. 1:    cmpl    a0,a2
  1375.     jeq    2f        | while (src < limit)
  1376.     moveb    a0@+,a1@+    |  *dest++ = *src++;
  1377.     jra    1b
  1378. 2:
  1379.                 | /* copy bootinfo to end of bss */
  1380.     movel    a3,a0        | src = (u_long *)(memptr+kernel_size);
  1381.     addl    d2,a0        | dest = end of bss (already in a1)
  1382.     movel    d3,d7        | count = bi_size
  1383.     subql    #1,d7
  1384. 1:    moveb    a0@+,a1@+    | while (--count > -1)
  1385.     dbra    d7,1b        |     *dest++ = *src++
  1386.  
  1387.                 | /* copy the ramdisk to the top of memory */
  1388.                 | /* (from back to front) */
  1389.     movel    a4,a1        | dest = (u_long *)(start_mem+mem_size);
  1390.     addl    d0,a1
  1391.     movel    a3,a2        | limit = (u_long *)(memptr+kernel_size +
  1392.     addl    d2,a2        |             bi_size);
  1393.     addl    d3,a2
  1394.     movel    a2,a0        | src = (u_long *)((u_long)limit+rd_size);
  1395.     addl    d1,a0
  1396. 1:    cmpl    a0,a2
  1397.     beqs    2f        | while (src > limit)
  1398.     moveb    a0@-,a1@-    |     *--dest = *--src;
  1399.     bras    1b
  1400. 2:
  1401.                 | /* jump to start of kernel */
  1402.     movel    a4,a0        | jump_to (start_mem);
  1403.     jmp    a0@
  1404. "
  1405. SYMBOL_NAME_STR(_copyallend) ":
  1406. ");
  1407.  
  1408.  
  1409.     /*
  1410.      *    Test for a MapROMmed A3640 Board
  1411.      */
  1412.  
  1413. asm(".text\n"
  1414. ALIGN_STR "\n"
  1415. SYMBOL_NAME_STR(_maprommed) ":
  1416.     oriw    #0x0700,sr
  1417.     moveml    #0x3f20,sp@-
  1418.                 | /* Save cache settings */
  1419.     .long    0x4e7a1002    | movec cacr,d1 */
  1420.                 | /* Save MMU settings */
  1421.     .long    0x4e7a2003    | movec tc,d2
  1422.     .long    0x4e7a3004    | movec itt0,d3
  1423.     .long    0x4e7a4005    | movec itt1,d4
  1424.     .long    0x4e7a5006    | movec dtt0,d5
  1425.     .long    0x4e7a6007    | movec dtt1,d6
  1426.     moveq    #0,d0
  1427.     movel    d0,a2
  1428.                 | /* Disable caches */
  1429.     .long    0x4e7b0002    | movec d0,cacr
  1430.                 | /* Disable MMU */
  1431.     .long    0x4e7b0003    | movec d0,tc
  1432.     .long    0x4e7b0004    | movec d0,itt0
  1433.     .long    0x4e7b0005    | movec d0,itt1
  1434.     .long    0x4e7b0006    | movec d0,dtt0
  1435.     .long    0x4e7b0007    | movec d0,dtt1
  1436.     lea    0x07f80000,a0
  1437.     lea    0x00f80000,a1
  1438.     movel    a0@,d7
  1439.     cmpl    a1@,d7
  1440.     jne    1f
  1441.     movel    d7,d0
  1442.     notl    d0
  1443.     movel    d0,a0@
  1444.     nop            | /* Thanks to Jörg Mayer! */
  1445.     cmpl    a1@,d0
  1446.     jne    1f
  1447.     moveq    #-1,d0        | /* MapROMmed A3640 present */
  1448.     movel    d0,a2
  1449. 1:    movel    d7,a0@
  1450.                 | /* Restore MMU settings */
  1451.     .long    0x4e7b2003    | movec d2,tc
  1452.     .long    0x4e7b3004    | movec d3,itt0
  1453.     .long    0x4e7b4005    | movec d4,itt1
  1454.     .long    0x4e7b5006    | movec d5,dtt0
  1455.     .long    0x4e7b6007    | movec d6,dtt1
  1456.                 | /* Restore cache settings */
  1457.     .long    0x4e7b1002    | movec d1,cacr
  1458.     movel    a2,d0
  1459.     moveml    sp@+,#0x04fc
  1460.     rte
  1461. ");
  1462.  
  1463.  
  1464.     /*
  1465.      *    Reset functions for nasty Zorro boards
  1466.      */
  1467.  
  1468. static void reset_rb3(const struct ConfigDev *cd)
  1469. {
  1470.     volatile u_char *rb3_reg = (u_char *)(cd->cd_BoardAddr+0x01002000);
  1471.  
  1472.     /* FN: If a Rainbow III board is present, reset it to disable */
  1473.     /* its (possibly activated) vertical blank interrupts as the */
  1474.     /* kernel is not yet prepared to handle them (level 6). */
  1475.  
  1476.     /* set RESET bit in special function register */
  1477.     *rb3_reg = 0x01;
  1478.     /* actually, only a few cycles delay are required... */
  1479.     Sleep(1000000);
  1480.     /* clear reset bit */
  1481.     *rb3_reg = 0x00;
  1482. }
  1483.  
  1484. static void reset_piccolo(const struct ConfigDev *cd)
  1485. {
  1486.     volatile u_char *piccolo_reg = (u_char *)(cd->cd_BoardAddr+0x8000);
  1487.  
  1488.     /* FN: the same stuff as above, for the Piccolo board. */
  1489.     /* this also has the side effect of resetting the board's */
  1490.     /* output selection logic to use the Amiga's display in single */
  1491.     /* monitor systems - which is currently what we want. */
  1492.  
  1493.     /* set RESET bit in special function register */
  1494.     *piccolo_reg = 0x01;
  1495.     /* actually, only a few cycles delay are required... */
  1496.     Sleep(1000000);
  1497.     /* clear reset bit */
  1498.     *piccolo_reg = 0x51;
  1499. }
  1500.  
  1501. static void reset_sd64(const struct ConfigDev *cd)
  1502. {
  1503.     volatile u_char *sd64_reg = (u_char *)(cd->cd_BoardAddr+0x8000);
  1504.  
  1505.     /* FN: the same stuff as above, for the SD64 board. */
  1506.     /* just as on the Piccolo, this also resets the monitor switch */
  1507.  
  1508.     /* set RESET bit in special function register */
  1509.     *sd64_reg = 0x1f;
  1510.     /* actually, only a few cycles delay are required... */
  1511.     Sleep(1000000);
  1512.     /* clear reset bit AND switch monitor bit (0x20) */
  1513.     *sd64_reg = 0x4f;
  1514. }
  1515.  
  1516. static void reset_a2065(const struct ConfigDev *cd)
  1517. {
  1518.     volatile u_short *lance_rdp = (u_short *)(cd->cd_BoardAddr+0x4000);
  1519.     volatile u_short *lance_rap = (u_short *)(cd->cd_BoardAddr+0x4002);
  1520.  
  1521.     Disable();
  1522.  
  1523.     /* Stop the card */
  1524.     *lance_rap = 0; /* PCnet-ISA Controller Status (CSR0) */
  1525.     *lance_rdp = 4; /* STOP */
  1526.  
  1527.     Enable();
  1528. }
  1529.     
  1530. static void reset_ariadne(const struct ConfigDev *cd)
  1531. {
  1532.     volatile u_short *lance_rdp = (u_short *)(cd->cd_BoardAddr+0x0370);
  1533.     volatile u_short *lance_rap = (u_short *)(cd->cd_BoardAddr+0x0372);
  1534.     volatile u_short *lance_reset = (u_short *)(cd->cd_BoardAddr+0x0374);
  1535.  
  1536.     volatile u_char *pit_paddr = (u_char *)(cd->cd_BoardAddr+0x1004);
  1537.     volatile u_char *pit_pbddr = (u_char *)(cd->cd_BoardAddr+0x1006);
  1538.     volatile u_char *pit_pacr = (u_char *)(cd->cd_BoardAddr+0x100b);
  1539.     volatile u_char *pit_pbcr = (u_char *)(cd->cd_BoardAddr+0x100e);
  1540.     volatile u_char *pit_psr = (u_char *)(cd->cd_BoardAddr+0x101a);
  1541.  
  1542.     u_short in;
  1543.  
  1544.     Disable();
  1545.  
  1546.     /*
  1547.      *    Reset the Ethernet part (Am79C960 PCnet-ISA)
  1548.      */
  1549.  
  1550.     in = *lance_reset;   /* Reset Chip on Read Access */
  1551.     *lance_rap = 0x0000; /* PCnet-ISA Controller Status (CSR0) */
  1552.     *lance_rdp = 0x0400; /* STOP */
  1553.  
  1554.     /*
  1555.      *    Reset the Parallel part (MC68230 PI/T)
  1556.      */
  1557.  
  1558.     *pit_pacr &= 0xfd;   /* Port A Control Register */
  1559.     *pit_pbcr &= 0xfd;   /* Port B Control Register */
  1560.     *pit_psr = 0x05;     /* Port Status Register */
  1561.     *pit_paddr = 0x00;   /* Port A Data Direction Register */
  1562.     *pit_pbddr = 0x00;   /* Port B Data Direction Register */
  1563.  
  1564.     Enable();
  1565. }
  1566.  
  1567. static void reset_hydra(const struct ConfigDev *cd)
  1568. {
  1569.     volatile u_char *nic_cr  = (u_char *)(cd->cd_BoardAddr+0xffe1);
  1570.     volatile u_char *nic_isr = (u_char *)(cd->cd_BoardAddr+0xffe1 + 14);
  1571.     int n = 5000;
  1572.  
  1573.     Disable();
  1574.  
  1575.     *nic_cr = 0x21;    /* nic command register: software reset etc. */
  1576.     while (((*nic_isr & 0x80) == 0) && --n)  /* wait for reset to complete */
  1577.     ;
  1578.  
  1579.     Enable();
  1580. }
  1581.  
  1582. #if 0
  1583. static void reset_a2060(const struct ConfigDev *cd)
  1584. {
  1585. #error reset_a2060: not yet implemented
  1586. }
  1587. #endif
  1588.  
  1589.  
  1590. #ifdef ZKERNEL
  1591.  
  1592. #define    ZFILE_CHUNK_BITS    16  /* chunk is 64 KB */
  1593. #define    ZFILE_CHUNK_SIZE    (1 << ZFILE_CHUNK_BITS)
  1594. #define    ZFILE_CHUNK_MASK    (ZFILE_CHUNK_SIZE-1)
  1595. #define    ZFILE_N_CHUNKS        (2*1024*1024/ZFILE_CHUNK_SIZE)
  1596.  
  1597. /* variables for storing the uncompressed data */
  1598. static char *ZFile[ZFILE_N_CHUNKS];
  1599. static int ZFileSize = 0;
  1600. static int ZFpos = 0;
  1601. static int Zwpos = 0;
  1602.  
  1603. static int Zinfd = 0;         /* fd of compressed file */
  1604.  
  1605. /*
  1606.  * gzip declarations
  1607.  */
  1608.  
  1609. #define OF(args)  args
  1610.  
  1611. #define memzero(s, n)     memset ((s), 0, (n))
  1612.  
  1613. typedef unsigned char  uch;
  1614. typedef unsigned short ush;
  1615. typedef unsigned long  ulg;
  1616.  
  1617. #define INBUFSIZ 4096
  1618. #define WSIZE 0x8000    /* window size--must be a power of two, and */
  1619.             /*  at least 32K for zip's deflate method */
  1620.  
  1621. static uch *inbuf;
  1622. static uch *window;
  1623.  
  1624. static unsigned insize = 0;  /* valid bytes in inbuf */
  1625. static unsigned inptr = 0;   /* index of next byte to be processed in inbuf */
  1626. static unsigned outcnt = 0;  /* bytes in output buffer */
  1627. static int exit_code = 0;
  1628. static long bytes_out = 0;
  1629.  
  1630. #define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
  1631.         
  1632. /* Diagnostic functions (stubbed out) */
  1633. #define Assert(cond,msg)
  1634. #define Trace(x)
  1635. #define Tracev(x)
  1636. #define Tracevv(x)
  1637. #define Tracec(c,x)
  1638. #define Tracecv(c,x)
  1639.  
  1640. #define STATIC static
  1641.  
  1642. static int  fill_inbuf(void);
  1643. static void flush_window(void);
  1644. static void error(char *m);
  1645. static void gzip_mark(void **);
  1646. static void gzip_release(void **);
  1647.  
  1648. #define malloc(x)    AllocVec(x, MEMF_FAST | MEMF_PUBLIC)
  1649. #define free(x)        FreeVec(x)
  1650.  
  1651. #ifdef LILO
  1652. #include "inflate.c"
  1653. #else
  1654. #include "../../../../lib/inflate.c"
  1655. #endif
  1656.  
  1657. static void gzip_mark(void **ptr)
  1658. {
  1659. }
  1660.  
  1661. static void gzip_release(void **ptr)
  1662. {
  1663. }
  1664.  
  1665.  
  1666. /*
  1667.  * Fill the input buffer. This is called only when the buffer is empty
  1668.  * and at least one byte is really needed.
  1669.  */
  1670. static int fill_inbuf(void)
  1671. {
  1672.     if (exit_code)
  1673.     return -1;
  1674.  
  1675.     insize = Read(Zinfd, inbuf, INBUFSIZ);
  1676.     if (insize <= 0)
  1677.     return -1;
  1678.  
  1679.     inptr = 1;
  1680.     return(inbuf[0]);
  1681. }
  1682.  
  1683. /*
  1684.  * Write the output window window[0..outcnt-1] and update crc and bytes_out.
  1685.  * (Used for the decompressed data only.)
  1686.  */
  1687. static void flush_window(void)
  1688. {
  1689.     ulg c = crc;         /* temporary variable */
  1690.     unsigned n;
  1691.     uch *in, ch;
  1692.     int chunk = Zwpos >> ZFILE_CHUNK_BITS;
  1693.  
  1694.     if (exit_code)
  1695.     return;
  1696.  
  1697.     if (chunk >= ZFILE_N_CHUNKS) {
  1698.     error("Compressed image too large! Aborting.\n");
  1699.     return;
  1700.     }
  1701.     if (!ZFile[chunk]) {
  1702.     if (!(ZFile[chunk] = (char *)AllocMem(ZFILE_CHUNK_SIZE,
  1703.                           MEMF_FAST | MEMF_PUBLIC))) {
  1704.         error("Out of memory for decompresing kernel image\n");
  1705.         return;
  1706.     }
  1707.     }
  1708.     memcpy(ZFile[chunk] + (Zwpos & ZFILE_CHUNK_MASK), window, outcnt);
  1709.     Zwpos += outcnt;
  1710.     
  1711. #define    DISPLAY_BITS 10
  1712.     if ((Zwpos & ((1 << DISPLAY_BITS)-1)) == 0)
  1713.     PutChar('.');
  1714.     
  1715.     in = window;
  1716.     for (n = 0; n < outcnt; n++) {
  1717.     ch = *in++;
  1718.     c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
  1719.     }
  1720.     crc = c;
  1721.     bytes_out += (ulg)outcnt;
  1722.     outcnt = 0;
  1723. }
  1724.  
  1725. static void error(char *x)
  1726. {
  1727.     Printf("\n%s", x);
  1728.     exit_code = 1;
  1729. }
  1730.  
  1731. static inline int call_sub(int (*func)(void), void *stackp)
  1732. {
  1733.     register int _res __asm("d0");
  1734.     register int (*a0)(void) __asm("a0") = func;
  1735.     register int (*a1)(void) __asm("a1") = stackp;
  1736.  
  1737.     __asm __volatile ("movel sp,a2;"
  1738.                   "movel a1,sp;"
  1739.                   "jsr a0@;"
  1740.                   "movel a2,sp"
  1741.               : "=r" (_res)
  1742.               : "r" (a0), "r" (a1)
  1743.               : "a0", "a1", "a2", "d0", "d1", "memory");
  1744.     return(_res);
  1745. }
  1746.  
  1747. static int load_zkernel(int fd)
  1748. {
  1749.     int i, err = -1;
  1750. #define ZSTACKSIZE    (16384)
  1751.     u_long *zstack;
  1752.     
  1753.     for (i = 0; i < ZFILE_N_CHUNKS; ++i)
  1754.     ZFile[i] = NULL;
  1755.     Zinfd = fd;
  1756.     Seek(fd, 0);
  1757.     
  1758.     if (!(inbuf = (uch *)AllocMem(INBUFSIZ, MEMF_FAST | MEMF_PUBLIC)))
  1759.     Puts("Couldn't allocate gunzip buffer\n");
  1760.     else {
  1761.     if (!(window = (uch *)AllocMem(WSIZE, MEMF_FAST | MEMF_PUBLIC)))
  1762.         Puts("Couldn't allocate gunzip window\n");
  1763.     else {
  1764.         if (!(zstack = (u_long *)AllocMem(ZSTACKSIZE,
  1765.                               MEMF_FAST | MEMF_PUBLIC)))
  1766.         Puts("Couldn't allocate gunzip stack\n");
  1767.         else {
  1768.         Puts("Uncompressing kernel image ");
  1769.         makecrc();
  1770.         if (!(err = call_sub(gunzip, (char *)zstack+ZSTACKSIZE)))
  1771.             Puts("done\n");
  1772.         ZFileSize = Zwpos;
  1773.         FreeMem(zstack, ZSTACKSIZE);
  1774.         }
  1775.         FreeMem(window, WSIZE);
  1776.         window = NULL;
  1777.     }
  1778.     FreeMem(inbuf, INBUFSIZ);
  1779.     inbuf = NULL;
  1780.     }
  1781.     Close(Zinfd);    /* input file not needed anymore */
  1782.     return(err);
  1783. }
  1784.  
  1785.  
  1786. /* Note about the read/lseek wrapper and its memory management: It assumes
  1787.  * that all seeks are only forward, and thus data already read or skipped can
  1788.  * be freed. This is true for current organization of bootstrap and kernels.
  1789.  * Little exception: The struct kexec at the start of the file. After reading
  1790.  * it, there may be a seek back to the end of the file. But this currently
  1791.  * doesn't hurt. (Roman)
  1792.  */
  1793.  
  1794. static int KRead(int fd, void *buf, int cnt)
  1795. {
  1796.     unsigned done = 0;
  1797.     
  1798.     if (!ZFileSize)
  1799.     return(Read(fd, buf, cnt));
  1800.     
  1801.     if (ZFpos + cnt > ZFileSize)
  1802.     cnt = ZFileSize - ZFpos;
  1803.     
  1804.     while (cnt > 0) {
  1805.     unsigned chunk = ZFpos >> ZFILE_CHUNK_BITS;
  1806.     unsigned endchunk = (chunk+1) << ZFILE_CHUNK_BITS;
  1807.     unsigned n = cnt;
  1808.  
  1809.     if (ZFpos + n > endchunk)
  1810.         n = endchunk - ZFpos;
  1811.     memcpy(buf, ZFile[chunk] + (ZFpos & ZFILE_CHUNK_MASK), n);
  1812.     cnt -= n;
  1813.     buf += n;
  1814.     done += n;
  1815.     ZFpos += n;
  1816.  
  1817.     if (ZFpos == endchunk) {
  1818.         FreeMem(ZFile[chunk], ZFILE_CHUNK_SIZE);
  1819.         ZFile[chunk] = NULL;
  1820.     }
  1821.     }
  1822.  
  1823.     return(done);
  1824. }
  1825.  
  1826.  
  1827. static int KSeek(int fd, int offset)
  1828. {
  1829.     unsigned oldpos, oldchunk, newchunk;
  1830.  
  1831.     if (!ZFileSize)
  1832.     return(Seek(fd, offset));
  1833.  
  1834.     oldpos = ZFpos;
  1835.     ZFpos = offset;
  1836.     if (ZFpos < 0) {
  1837.     ZFpos = 0;
  1838.     return(-1);
  1839.     } else if (ZFpos > ZFileSize) {
  1840.     ZFpos = ZFileSize;
  1841.     return(-1);
  1842.     }
  1843.  
  1844.     /* free memory of skipped-over data */
  1845.     oldchunk = oldpos >> ZFILE_CHUNK_BITS;
  1846.     newchunk = ZFpos  >> ZFILE_CHUNK_BITS;
  1847.     while(oldchunk < newchunk) {
  1848.     if (ZFile[oldchunk]) {
  1849.         FreeMem(ZFile[oldchunk], ZFILE_CHUNK_SIZE);
  1850.         ZFile[oldchunk] = NULL;
  1851.     }
  1852.     ++oldchunk;
  1853.     }
  1854.     return(ZFpos);
  1855. }
  1856.  
  1857.  
  1858. static void free_zfile(void)
  1859. {
  1860.     int i;
  1861.  
  1862.     for (i = 0; i < ZFILE_N_CHUNKS; ++i)
  1863.     if (ZFile[i]) {
  1864.         FreeMem(ZFile[i], ZFILE_CHUNK_SIZE);
  1865.         ZFile[i] = NULL;
  1866.     }
  1867. }
  1868.  
  1869. static int KClose(int fd)
  1870. {
  1871.     if (ZFileSize) {
  1872.     free_zfile();
  1873.     ZFileSize = 0;
  1874.     } else
  1875.     Close(fd);
  1876.     return(0);
  1877. }
  1878. #endif /* ZKERNEL */
  1879.